#include "misc.h"
#include "includes.h"


void addStyleXml(String tag, Colour colour, XmlElement *whereToAdd)
{
XmlElement *mainStyle,*normal,*highlited;
XmlElement *tmp, *tmp2;
String ABGR, ARGB;

mainStyle=new XmlElement("StyleMap");
normal=new XmlElement("Style");
highlited=new XmlElement("Style");

normal->setAttribute(T("id"), "nor_"+tag);
highlited->setAttribute(T("id"), "high_"+tag);

whereToAdd->addChildElement(mainStyle);
whereToAdd->addChildElement(normal);
whereToAdd->addChildElement(highlited);

mainStyle->setAttribute(T("id"), tag);

mainStyle->addChildElement(tmp=new XmlElement("Pair"));
tmp2=new XmlElement("key");
tmp2->addTextElement("normal");
tmp->addChildElement(tmp2);
tmp2=new XmlElement("styleUrl");
tmp2->addTextElement("#"+("nor_"+tag));
tmp->addChildElement(tmp2);

mainStyle->addChildElement(tmp=new XmlElement("Pair"));
tmp2=new XmlElement("key");
tmp2->addTextElement("highlight");
tmp->addChildElement(tmp2);
tmp2=new XmlElement("styleUrl");
tmp2->addTextElement("#"+("high_"+tag));
tmp->addChildElement(tmp2);

tmp=new XmlElement("PolyStyle");
tmp->addChildElement((tmp2=new XmlElement("color")));
ARGB=colour.toString();
ABGR=ARGB.substring(0,2)+ARGB.substring(6,8)+ARGB.substring(4,6)+ARGB.substring(2,4);
tmp2->addTextElement(ABGR);

normal->addChildElement(tmp);

tmp=new XmlElement("PolyStyle");
tmp->addChildElement((tmp2=new XmlElement("color")));
ARGB=colour.toString();
ABGR=ARGB.substring(0,2)+ARGB.substring(6,8)+ARGB.substring(4,6)+ARGB.substring(2,4);
tmp2->addTextElement(ABGR);

highlited->addChildElement(tmp);


}
String leading2zero(String stringToExpand)
{
return ((stringToExpand.length()==1)?"0":"")+stringToExpand;
}
XmlElement* giveXMLtext(const String &tag, const String &value){
		XmlElement *newElement;
		newElement=new XmlElement(tag);
		newElement->addTextElement(value);
		return newElement;

}
XmlElement* makePolygon(XmlElement *parent){
		XmlElement *currPolygon, *ob, *lr, *coo;


		currPolygon=new XmlElement(T("Polygon"));

		currPolygon->addChildElement(giveXMLtext("extrude","0"));
		currPolygon->addChildElement(giveXMLtext("tessellate","0"));
		currPolygon->addChildElement(giveXMLtext("altitudeMode","relativeToSeaFloor"));

		parent->addChildElement(currPolygon);
		ob=new XmlElement(T("outerBoundaryIs"));
		currPolygon->addChildElement(ob);
		lr=new XmlElement(T("LinearRing"));
		ob->addChildElement(lr);
		coo=new XmlElement(T("coordinates"));
		lr->addChildElement(coo);

	return coo;
}
bool aupAlt2meter(String &value)
{
	int fl;
		if(value.containsIgnoreCase(T("FL")))
		{
		   value=value.fromFirstOccurrenceOf(T("FL"),false,true);
		   fl=value.getIntValue();
		   fl=(int)fl*100/(float)3.2808399;
		   value=String(fl);
		   return true;
		}
		if(value.containsIgnoreCase(T("FT"))) // gdyby kiedys wystapily, poki co nie ma
		{
		   value=value.fromFirstOccurrenceOf(T("FT"),false,true);
		   fl=value.getIntValue();
		   fl=(int)fl/(float)3.2808399;
		   value=String(fl);
		   return true;
		}
		if(value.containsIgnoreCase(T("GND")))
		{
		   value="0";
		   return true;
		}
		if(value.containsIgnoreCase(T("UNL")))
		{
		   value="14020";
		   return true;
		}
		if(value.containsIgnoreCase(T("A")))
		{
		   value=value.fromFirstOccurrenceOf(T("A"),false,true);
		   fl=value.getIntValue();
		   fl=(int)fl*100/(float)3.2808399;
		   value=String(fl);
		   return true;
		}
		if(value.containsIgnoreCase(T("F")))
		{
		   value=value.fromFirstOccurrenceOf(T("F"),false,true);
		   fl=value.getIntValue();
		   fl=(int)fl*100/(float)3.2808399;
		   value=String(fl);
		   return true;
		}
		return true;  //TODO: trzeba sprawdzic,czy wartosc jest poprawna w m i jak tak,to ok, jak nie, to false
}
bool placemark2dTo3d(XmlElement &placemark)
{
		int j;
		String tekst,up,down,temp;
		if(placemark.getChildByName(T("Polygon"))==0)
			return false;		//nie ma polygona wiec nic dla niego nie moge zrobic :(
		tekst=(placemark.getChildByName(T("description"))->getFirstChildElement()->getAttributeValue(0));
		if((!tekst.containsIgnoreCase(T("Upper limit:")))||(!tekst.containsIgnoreCase(T("Lower limit:"))))
		{
			return false; //TODO: bez gory i dolu nic nie moge zrobic, wiec wracam zero
		}
		up=tekst.fromFirstOccurrenceOf(T("Upper limit:"),0,1).trimStart().upToFirstOccurrenceOf(T(" "),0,1).trim();
		down=tekst.fromFirstOccurrenceOf(T("Lower limit:"),0,1).trimStart().upToFirstOccurrenceOf(T(" "),0,1).trim();
		aupAlt2meter(up);
		aupAlt2meter(down);


		XmlElement *coordinates=placemark.getChildByName(T("Polygon"))->getChildByName(T("outerBoundaryIs"))->getChildByName(T("LinearRing"))->getChildByName(T("coordinates"));

		StringArray cords;
		cords.addLines(coordinates->getAllSubText().trim()); //getFirstChildElement()->getAttributeValue(0)

		XmlElement *multigeometry=new XmlElement(T("MultiGeometry"));
		XmlElement *coo;
		placemark.replaceChildElement(placemark.getChildByName(T("Polygon")),multigeometry);

		coo=makePolygon(multigeometry);

		temp="\n"+cords.joinIntoString(T(", ")+up+T("\n"))+T(", ")+up+"\n";
		coo->addChildElement(XmlElement::createTextElement(temp));

		temp=String::empty;

		coo=makePolygon(multigeometry);
		temp="\n";
		for(j=cords.size()-1;j>=0;j--){
			temp+=cords[j]+", "+down+"\n";
		}
		coo->addChildElement(XmlElement::createTextElement(temp));

		temp=String::empty;

		for(j=0;j<=cords.size()-2;j++){		//ma sie zatrzymac na przedostatnim punkcie (bo bierze jeden w przod, oraz -1 bo ilosc
			temp=String::empty;

			coo=makePolygon(multigeometry);
			
			temp="\n";
			temp+=cords[j+1]+", "+up+"\n";
			temp+=cords[j]+", "+up+"\n";
			temp+=cords[j]+", "+down+"\n";
			temp+=cords[j+1]+", "+down+"\n";
			temp+=cords[j+1]+", "+up+"\n";
			coo->addChildElement(XmlElement::createTextElement(temp));
		}
		return true;
}
Converter::Converter(XmlElement *XMLout_,int count)
: ThreadWithProgressWindow (T("Converting 2d placemarks to 3d..."),
							true,
							true), XMLout(XMLout_), XMLoutcount(count)
{
	setStatusMessage (T("Getting ready..."));
}

Converter::~Converter()
{
}

void Converter::run()
{
	//setProgress (-1.0); // setting a value beyond the range 0 -> 1 will show a spinning bar..
	//setStatusMessage (T("Preparing to do some stuff..."));


	int i=0;
	XmlElement *placemark;
	forEachXmlChildElementWithTagName(*(this->XMLout->getChildByName(T("Document"))),placemark,T("Placemark"))
	{

		placemark2dTo3d(*placemark);
		// must check this as often as possible, because this is
		// how we know if the user's pressed 'cancel'
		if (threadShouldExit())
			return;

		// this will update the progress bar on the dialog box
		setProgress (i / (double) XMLoutcount);

		setStatusMessage (String (XMLoutcount - i++) + T(" things left to do..."));

	}
 //	setProgress (-1.0); // setting a value beyond the range 0 -> 1 will show a spinning bar..
	//setStatusMessage (T("Adding colours definitions!"));


}

